package externaldata.passageTrainReel;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.ProtocolException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

public class PassageTrainReelHelper {

	private static String api_url_base = "http://api.transilien.com/gare/";
	private static String api_url_suffix = "/depart/";
	
	private static String login = "upmc104";
	private static String password = "Xp597yAs";
	
	
	public static PackPassageTrainReel getDataFromAPI(String stationUIC) {

		// URL pour accéder à l'API
		URL url = null;
		
		try {
			url = new URL(api_url_base + stationUIC + api_url_suffix);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		
		if (url != null) {
			
			// Authentification pour l'API
			Authenticator.setDefault (new Authenticator() {
			    protected PasswordAuthentication getPasswordAuthentication() {
			        return new PasswordAuthentication (login, password.toCharArray());
			    }
			});
			
			// Etablissement de la connexion à l'API
			HttpURLConnection conn = null;
			
			try {
				conn = (HttpURLConnection) url.openConnection();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			if (conn != null) {
				
				try {
					conn.setRequestMethod("GET");
					conn.setRequestProperty("User-Agent", "Mozilla/5.0");
				} catch (ProtocolException e) {
					e.printStackTrace();
				}
				
				// Lecture de la réponse retournée par l'API
				int responseCode = 0;
				
				try {
					responseCode = conn.getResponseCode();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				if (responseCode == 200) {
					
					BufferedReader bReader = null;
					StringBuilder xmlResult = new StringBuilder();
					
					PackPassageTrainReel bundleData = new PackPassageTrainReel();
					
					try {
						// Récupération de l'heure de la requête HTTP en enlevant la précision sur les secondes
						SimpleDateFormat formater = new SimpleDateFormat("yyyyMMddHHmm");
						bundleData.dateHeureRequeteHttp = formater.parse(formater.format(conn.getDate()));
					} catch (ParseException e) {
						e.printStackTrace();
					}
					
					try {
						bReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
						
						String inputLine;
						
						while ((inputLine = bReader.readLine()) != null) {
							xmlResult.append(inputLine);
						}
					} catch (IOException e) {
						e.printStackTrace();
					} finally {

						if (bReader != null) {
							try {
								bReader.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
					
					try {
						bundleData.passagesList = PassageTrainReelHelper.parseStationData(xmlResult.toString());
						System.out.println("URL utilisée : " + url.toString());
					} catch (Exception e) {
						e.printStackTrace();
					}
					
					return bundleData;
				}
			}
		}
		
		return null;
	}
	
	
	private static List<PassageTrainReel> parseStationData(String xmlToParse) throws Exception {
		
		if (xmlToParse != null) {
			
			try {
				// Création d'un SAX parser standard
				SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

				// Utilisation du handler personnalisé
				PassageTrainReelHandler handler = new PassageTrainReelHandler();
				
				// Création d'un Stream contenant le XML à parser
				InputStream xmlStream = new ByteArrayInputStream(xmlToParse.getBytes());
				
				// Parsing
				parser.parse(xmlStream, handler);
				
				// On retourne le résultat du parsing
				return handler.getTrainList();
	  
			} catch (ParserConfigurationException e) { 
				System.err.println("Erreur de configuration du parseur lors de l'appel à newSAXParser()"); 
			} catch (SAXException e) { 
				System.err.println("Erreur de parsing lors de l'appel à parse()"); 
			} catch (IOException e) { 
				System.err.println("Erreur d'entrée/sortie lors de l'appel à parse()"); 
			}
		}
		
		return null;
	}
}
